﻿using System;
using System.Collections.Generic;

namespace Pfz.DynamicObjects
{
	/// <summary>
	/// A dictionary for data-type conversions used by the DelegatedTypeBuilder.
	/// </summary>
	public sealed class DelegatedTypeBuilderConversions
	{
		private Dictionary<KeyValuePair<Type, Type>, Delegate> _dictionary = new Dictionary<KeyValuePair<Type, Type>, Delegate>();
		
		/// <summary>
		/// Registers a new conversion from one data-type to another.
		/// </summary>
		public void Register<TFrom, TTo>(Func<TFrom, TTo> conversion)
		{
			if (conversion == null)
				throw new ArgumentNullException("conversion");
				
			_dictionary[new KeyValuePair<Type, Type>(typeof(TFrom), typeof(TTo))] = conversion;
		}
		
		/// <summary>
		/// Registers a new conversion from one data-type to another.
		/// The conversion will receive the parameter name as the first argument, so
		/// error messages can be formatted accordingly.
		/// </summary>
		public void Register<TFrom, TTo>(Func<string, TFrom, TTo> conversion)
		{
			if (conversion == null)
				throw new ArgumentNullException("conversion");

			_dictionary[new KeyValuePair<Type, Type>(typeof(TFrom), typeof(TTo))] = conversion;
		}
		
		/// <summary>
		/// Tries to get a converter from one type to another.
		/// Returns null if the conversion is not found. It is up to the user
		/// to cast it accordingly to use.
		/// </summary>
		public Delegate TryGetConverter(Type from, Type to)
		{
			Delegate result;
			_dictionary.TryGetValue(new KeyValuePair<Type, Type>(from, to), out result);
			return result;
		}
	}
}
